#include "element.h"
#include "node.h"

#include <list>
#include <string>

using namespace std;

XmlElement::XmlElement() : AttrNode() {
	mChildren = new list<Node*>;
}

XmlElement::XmlElement(const XmlElement& e) : AttrNode(e) {
	mChildren = new list<Node*>;
	if (e.mChildren != NULL && e.mChildren->size() > 0) {
		
		for (list<Node*>::iterator iter=(e.mChildren->begin());
		 iter!=(e.mChildren->end());
		 iter++) {
		 	Node* newChild = (*iter)->clone();
			mChildren->push_back(newChild);
			newChild->setParent(this);
		}
	}
}
XmlElement::XmlElement(std::string tag) : AttrNode(tag) {
	mChildren = new list<Node*>;
}
XmlElement::XmlElement(std::string tag, std::string ns) : AttrNode(tag, ns) {
	mChildren = new list<Node*>;
}

XmlElement::~XmlElement() {

	if (mChildren != NULL && mChildren->size() > 0) {
		
		for (list<Node*>::iterator iter=(mChildren->begin());
		 iter!=(mChildren->end());
		 iter++) {
			delete (*iter);
		}
		
		delete mChildren;
	}
}

void XmlElement::setChildren(list<Node*> *children) {
	delete mChildren;
	mChildren = children;
	
	for (list<Node*>::iterator iter=(mChildren->begin());
		 iter!=(mChildren->end());
		 iter++) {
		 
			(*iter)->setParent(this);
	}
}

list<Node*>* XmlElement::getChildren() {
	return mChildren;
}

void XmlElement::print(ostream& out) {
	
	out << "<" << getNSTag();
	
	printAttributes(out);
	
	// print all the children of this Element
	if (mChildren != NULL && mChildren->size() > 0) {
		out << ">\n";
		
		for (list<Node*>::iterator iter=(mChildren->begin());
		 iter!=(mChildren->end());
		 iter++) {
			(*iter)->print(out);
		}
		out << "</" << getNSTag() << ">\n";
	} else {
		out << "/>\n";
	}
	
}

XmlElement* XmlElement::clone() const {
	XmlElement *element = new XmlElement(*this);
	/*if (mChildren != NULL && mChildren->size() > 0) {
		
		for (list<Node*>::iterator iter=(mChildren->begin());
		 iter!=(mChildren->end());
		 iter++) {
			element.mChildren.add((*iter)->clone());
		}
	}*/
	return element;
}

void XmlElement::addChild (Node *node) {
	if (mChildren != NULL) {
		mChildren->push_back(node);
		node->setParent(this);
	}
}

void XmlElement::removeChild (Node *node) {
	if (mChildren != NULL) {
		mChildren->remove(node);
		node->setParent(NULL);
	}
}

XmlElement* XmlElement::getElement(Node *node) {
	return dynamic_cast<XmlElement*>(node);
}
